package difftest

import com.sun.jna.Platform.isWindows
import com.sun.jna.{Library, Native, NativeLibrary, Pointer}

object DifftestCoreNative {
  trait RefLib extends Library {
    def difftest_init(port: Int): Unit

    def difftest_raise_intr(no: Int): Unit

    def difftest_exec(n: Long): Unit

    def difftest_guided_exec(guide: Pointer): Unit

    def difftest_memcpy(addr: Int, buf: Pointer, n: Int, direction: Boolean): Unit

    def difftest_regcpy(buf: Pointer, direction: Boolean, copy_csr: Boolean): Unit

    def difftest_timercpy(buf: Pointer): Unit

    def difftest_estat_sync(index: Int, mask: Int): Unit

    def difftest_tlb_cpy(index: Int, dut: Pointer): Unit

    def difftest_tlbfill_index_set(index: Int): Unit

    def difftest_csrcpy(dut: Pointer, direction: Boolean): Unit

    def difftest_uarshstatus_cpy(dut: Pointer, direction: Boolean): Unit

    def difftest_store_commit(saddr: Long, sdata: Long): Int

    def backend_load_image(filename: String, addr: Int): Int

    def backend_init(): Unit

    def load_img(file: String, address: Int): Int

    def difftest_get_pc(): Int

    def isa_reg_display(): Unit

    def difftest_release(): Unit
  }

  object RefLib {
    val TO_DUT = false
    val TO_REF = true

    val NAME_NEMU =
      if (isWindows) "bin/libnemu-ref"
      else "nemu-ref"
    val NAME_DEFAULT = NAME_NEMU

    def init(libName: String): RefLib = Native.load(libName, classOf[DifftestCoreNative.RefLib])

    def init(): RefLib = init(NAME_DEFAULT)

    def release() = {
      val lab = NativeLibrary.getInstance(NAME_DEFAULT)
      lab.dispose()
      System.gc()
    }
  }
}
